﻿Imports IICBusinessLogic
Imports IICBusinessLogic.PeriodProcessing

Public Class PeriodProcessorTestUtils

    Private Shared _lessonCodeCounter As Integer = 0
    Private Shared _studentCounter As Integer = 0

    Public Shared diplomaSuperType As DiplomaSuperType


    Public Shared Sub initialize()

        _lessonCodeCounter = ModelContext.CurrentDBUtils.getIntValue("select max(LessonId)+1 from Lesson")
        _studentCounter = ModelContext.CurrentDBUtils.getIntValue("select max(StudentId)+1 from Student")

        diplomaSuperType = DiplomaSuperTypeFactory.Create
        diplomaSuperType.DiplomaSuperTypeName = "test " & Now
        diplomaSuperType.DiplomaSuperTypeCode = "TST"
        DiplomaSuperTypeDataUtils.saveDiplomaSuperType(diplomaSuperType)

    End Sub

    Public Shared Function getNextStudentCounter() As Integer

        _studentCounter = _studentCounter + 1
        Return _studentCounter

    End Function
    ''' <summary>
    ''' Creates a diplomaType, 1 lesson and a 1 certificationType. 
    ''' Then, it links the CertificationType with the Diploma as a requirement 
    ''' and the lesson requiered for the Certification type .
    ''' </summary>
    ''' <remarks></remarks>
    Public Shared Function createDiplomaWithOneCertReqOneLesson() As DiplomaType

        Dim diplTypeName As String = "Test Diploma " & ModelContext.CurrentDBUtils.getIntValue("select count(*) from DiplomaType")

        Dim certCount As Integer = ModelContext.CurrentDBUtils.getIntValue("select count(*) from CertificationType")

        'create a diploma type
        Dim diploma As DiplomaType = DiplomaTypeFactory.Create
        diploma.DiplomaType = diplTypeName
        diploma.DiplomaSuperTypeId = PeriodProcessorTestUtils.diplomaSuperType.DiplomaSuperTypeId

        'create 2 certificates
        Dim cert1 As CertificationType = CertificationTypeFactory.Create
        cert1.CertificationType = "Test Cert " & certCount
        cert1.DiplomaSuperTypeId = PeriodProcessorTestUtils.diplomaSuperType.DiplomaSuperTypeId

        'to link the new diploma to the new certificates as requirements, 
        'call method that creates a diploma requirement from a certificate
        diploma.AddCertificationRequirement(cert1)

        Dim lssReq As Lesson = PeriodProcessorTestUtils.CreateLesson(100, 70)

        'add 2 lessons as certificate requirements
        cert1.AddLessonRequirement(lssReq)

        Dim d As New DiplomaTypeDBMapper()
        d.save(diploma)

        'after save, null out diploma variable and reload from database
        diploma = Nothing
        diploma = d.findWhere("DiplomaType={0}", diplTypeName)
        'the {0} notation is used to create parametrized sql statements.
        'to pass more than one parameter, use {0},{1},{2} etc. and pass then as the second argument.
        'example: 
        Assert.IsTrue(diploma IsNot Nothing)
        Assert.AreEqual(1, diploma.DiplomaRequirements.Count)
        Assert.IsTrue(diploma.getDiplomaRequirement(0).Certification IsNot Nothing)
        Assert.AreEqual(1, diploma.getDiplomaRequirement(0).Certification.CertificationRequirements.Count, _
                      "Expected diploma's required certification to have at least one CertificationRequirement")

        Assert.AreEqual(1, lssReq.CertificationRequirements.Count, _
                      "Expected lesson1 to have at least one CertificationRequirement")

        Return diploma

    End Function

    ''' <summary>
    ''' Creates a diplomaType, 3 lessons and 2 certificationTypes. 
    ''' Then, it links the CertificationType with the Diploma as a requirement 
    ''' and the 2 lesons requiered for the Certification type
    ''' </summary>
    ''' <remarks></remarks>
    Public Shared Function createDiplomaWith2CertReq() As DiplomaType

        Dim cert1 As CertificationType = Nothing
        Dim cert2 As CertificationType = Nothing

        Dim diplTypeName As String = "Test Diploma " & _
            ModelContext.CurrentDBUtils.getIntValue("select count(*) from DiplomaType")

        Dim maxCertId As Integer = ModelContext.CurrentDBUtils.getIntValue("select max(CertificationTypeId)+1 from CertificationType")

        'create a diploma type
        Dim diploma As DiplomaType = DiplomaTypeFactory.Create
        diploma.DiplomaType = diplTypeName
        diploma.DiplomaSuperTypeId = PeriodProcessorTestUtils.diplomaSuperType.DiplomaSuperTypeId

        'create 2 certificates
        cert1 = CertificationTypeFactory.Create
        cert1.CertificationType = "Test Cert " & maxCertId
        cert1.DiplomaSuperTypeId = PeriodProcessorTestUtils.diplomaSuperType.DiplomaSuperTypeId

        cert2 = CertificationTypeFactory.Create
        cert2.CertificationType = "Test Cert " & CStr((maxCertId + 1))
        cert2.DiplomaSuperTypeId = PeriodProcessorTestUtils.diplomaSuperType.DiplomaSuperTypeId

        'to link the new diploma to the new certificates as requirements, 
        'call method that creates a diploma requirement from a certificate
        diploma.AddCertificationRequirement(cert1)
        diploma.AddCertificationRequirement(cert2)
        Dim lesson1 As Lesson = PeriodProcessorTestUtils.CreateLesson(100, 70)
        Dim lesson2 As Lesson = PeriodProcessorTestUtils.CreateLesson(100, 80)
        Dim lesson3 As Lesson = PeriodProcessorTestUtils.CreateLesson(100, 80)

        LessonDataUtils.saveLesson(lesson1, lesson2, lesson3)

        'add 2 lessons on each certification as certificate requirements
        cert1.AddLessonRequirement(lesson1)
        cert1.AddLessonRequirement(lesson2)

        cert2.AddLessonRequirement(lesson3)
        cert2.AddLessonRequirement(lesson1)

        Dim d As New DiplomaTypeDBMapper()
        d.save(diploma)

        'after save, null out diploma variable and reload from database
        diploma = Nothing
        diploma = d.findWhere("DiplomaType={0}", diplTypeName)
        'the {0} notation is used to create parametrized sql statements.
        'to pass more than one parameter, use {0},{1},{2} etc. and pass then as the second argument.
        'example: 
        Assert.IsTrue(diploma IsNot Nothing)
        Assert.AreEqual(2, diploma.DiplomaRequirements.Count)
        Assert.IsTrue(diploma.getDiplomaRequirement(0).Certification IsNot Nothing)
        Assert.IsTrue(diploma.getDiplomaRequirement(0).Certification.CertificationRequirements.Count > 0, _
                      "Expected diploma's required certification to have at least one CertificationRequirement")

        Assert.IsTrue(lesson1.CertificationRequirements.Count > 0, _
                      "Expected lesson1 to have at least one CertificationRequirement")
        Assert.IsTrue(lesson2.CertificationRequirements.Count > 0, _
          "Expected lesson1 to have at least one CertificationRequirement")
        Assert.IsTrue(lesson3.CertificationRequirements.Count > 0, _
         "Expected lesson1 to have at least one CertificationRequirement")

        Debug.WriteLine("Created Diploma: " & diploma.DiplomaType & ", id:(" & diploma.DiplomaTypeId & ")")
        Debug.WriteLine("Created cert1: " & cert1.CertificationType & ", id:(" & cert1.CertificationTypeId & ")")
        Debug.WriteLine("Created cert2: " & cert2.CertificationType & ", id:(" & cert1.CertificationTypeId & ")")

        Return diploma

    End Function

    Public Shared Function CreateClassAndAddStudentsAsClassMembers( _
                        ByVal lesson As Lesson, _
                        ByVal period As Period, _
                        ByVal ParamArray students() As Student) As PeriodClass


        Dim cls As PeriodClass = PeriodClassFactory.Create
        Dim studManager As IStudentClassManager = New StudentClassManagerFactory().getStudentClassManager

        cls.Lesson = lesson
        cls.PeriodId = period.PeriodId
        cls.ExamCenterID = 1 'cyprus exam center
        cls.PassGrade = lesson.DefaultPassGrade
        cls.MaxGrade = lesson.DefaultMaxGrade

        For Each stud As Student In students.ToList
            studManager.addStudentToClass(stud, cls)
        Next
        period.AddClass(cls)
        Return cls
    End Function

    ''' <summary>
    ''' Creates a diplomaType, -numberOfLessons- lessons and a certificationType. 
    ''' Then, it links the CertificationType with the Diploma as a requirement 
    ''' and the  -numberOfLessons- lesons requiered for the Certification type .
    ''' </summary>
    ''' <remarks></remarks>
    Public Shared Function createDiplomaWithOneCertReqAndXLessons( _
                     ByVal numberOfLessons As Integer) As DiplomaType

        Dim diplTypeName As String = "Test Diploma " & ModelContext.CurrentDBUtils.getIntValue("select count(*) from DiplomaType")
        Dim certCount As Integer = ModelContext.CurrentDBUtils.getIntValue("select count(*) from CertificationType")

        'create a diploma type
        Dim diploma As DiplomaType = DiplomaTypeFactory.Create
        diploma.DiplomaType = diplTypeName
        diploma.DiplomaSuperTypeId = PeriodProcessorTestUtils.diplomaSuperType.DiplomaSuperTypeId

        'create 2 certificates
        Dim cert1 As CertificationType = CertificationTypeFactory.Create
        cert1.CertificationType = "Test Cert " & certCount
        cert1.DiplomaSuperTypeId = PeriodProcessorTestUtils.diplomaSuperType.DiplomaSuperTypeId

        'to link the new diploma to the new certificates as requirements, 
        'call method that creates a diploma requirement from a certificate
        diploma.AddCertificationRequirement(cert1)
        For i As Integer = 1 To numberOfLessons
            Dim ls As Lesson = PeriodProcessorTestUtils.CreateLesson(100, 70)
            cert1.AddLessonRequirement(ls)
        Next

        Dim d As New DiplomaTypeDBMapper()
        d.save(diploma)

        'after save, null out diploma variable and reload from database
        diploma = Nothing
        diploma = d.findWhere("DiplomaType={0}", diplTypeName)
        'the {0} notation is used to create parametrized sql statements.
        'to pass more than one parameter, use {0},{1},{2} etc. and pass then as the second argument.
        'example: 
        Assert.IsTrue(diploma IsNot Nothing)
        Assert.AreEqual(1, diploma.DiplomaRequirements.Count)
        Assert.IsTrue(diploma.getDiplomaRequirement(0).Certification IsNot Nothing)

        If numberOfLessons > 0 Then
            Assert.IsTrue(diploma.getDiplomaRequirement(0).Certification.CertificationRequirements.Count > 0, _
                          "Expected diploma's required certification to have at least one CertificationRequirement")

        End If

        Return diploma

    End Function

    Public Shared Function createDiplomaWithXCertReq(ByVal numberOfCerts As Integer) As DiplomaType

        Dim diplTypeName As String = "Test Diploma " & ModelContext.CurrentDBUtils.getIntValue("select count(*) from DiplomaType")
        Dim certCount As Integer = ModelContext.CurrentDBUtils.getIntValue("select count(*) from CertificationType")

        'create a diploma type
        Dim diploma As DiplomaType = DiplomaTypeFactory.Create
        diploma.DiplomaType = diplTypeName
        diploma.DiplomaSuperTypeId = diplomaSuperType.DiplomaSuperTypeId


        For icerts As Integer = 1 To numberOfCerts
            'create x certificates
            Dim certNew As CertificationType = CertificationTypeFactory.Create
            certNew.CertificationType = "Test Cert " & certCount
            certNew.DiplomaSuperTypeId = diplomaSuperType.DiplomaSuperTypeId

            'to link the new diploma to the new certificates as requirements, 
            'call method that creates a diploma requirement from a certificate
            diploma.AddCertificationRequirement(certNew)

        Next

        Dim d As New DiplomaTypeDBMapper()
        d.save(diploma)


        Return diploma

    End Function

    Public Shared Function CreateLesson(Optional ByVal maxGrade As Integer = 100, _
                                  Optional ByVal passGrade As Integer = 70) _
                                  As Lesson

        Dim o As Object = New Object

        'create a Lesson
        SyncLock o
            _lessonCodeCounter = _lessonCodeCounter + 1
            Dim ls As Lesson = LessonFactory.Create
            ls.LessonCode = "T" & Format(_lessonCodeCounter, "000")
            ls.LessonName = "test Lesson " & ls.LessonCode
            ls.DefaultMaxGrade = maxGrade
            ls.DefaultPassGrade = passGrade
            'Debug.WriteLine("Lesson Code:" & ls.LessonCode)
            Return ls

        End SyncLock

    End Function

    

End Class
